package com.zlzlib.libscanqr;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.AttributeSet;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import com.zlzlib.libscan.BaseScanView;
import com.zlzlib.libscan.ScanResult;
import com.zlzlib.libscanqr.QrCodeDecoder;
import com.zlzlib.libscanqr.QrCodeType;

import java.util.Map;

/**
 * Created by zlz on 2018/9/17.
 * 二维码扫描 控件
 */
public class QrScanView extends BaseScanView {

    private MultiFormatReader mMultiFormatReader;
    private Map<DecodeHintType, Object> mHintMap;
    protected QrCodeType mQrCodeType = QrCodeType.HIGH_FREQUENCY;

    public QrScanView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setupReader();
    }

    @Override
    protected ScanResult processBitmapData(Bitmap bitmap) {
        return new ScanResult(QrCodeDecoder.syncDecodeQRCode(bitmap));
    }

    @Override
    protected ScanResult processData(byte[] data, int width, int height, boolean isRetry) {
        String result = null;
        Result rawResult = null;
        Rect scanBoxAreaRect = null;
        //通过 zxing  解析图像数据
        try {
            PlanarYUVLuminanceSource source;
            scanBoxAreaRect = scanBox.getScanBoxAreaRect(height, width);
            if (scanBoxAreaRect != null) {
                source = new PlanarYUVLuminanceSource(data, width, height, scanBoxAreaRect.left, scanBoxAreaRect.top, scanBoxAreaRect.width(),
                        scanBoxAreaRect.height(), isRetry);
            } else {
                source = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, isRetry);
            }
            rawResult = mMultiFormatReader.decodeWithState(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
            if (rawResult == null) {
                rawResult = mMultiFormatReader.decodeWithState(new BinaryBitmap(new HybridBinarizer(source)));
            }
            if (null != rawResult) {
                result = rawResult.getText();
            }
        } catch (Exception e) {
        } finally {
            mMultiFormatReader.reset();
        }
        return new ScanResult(result);
    }

    private void setupReader() {
        mMultiFormatReader = new MultiFormatReader();
        if (mQrCodeType == QrCodeType.ONE_DIMENSION) {
            mMultiFormatReader.setHints(QrCodeDecoder.ONE_DIMENSION_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.TWO_DIMENSION) {
            mMultiFormatReader.setHints(QrCodeDecoder.TWO_DIMENSION_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.ONLY_QR_CODE) {
            mMultiFormatReader.setHints(QrCodeDecoder.QR_CODE_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.ONLY_CODE_128) {
            mMultiFormatReader.setHints(QrCodeDecoder.CODE_128_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.ONLY_EAN_13) {
            mMultiFormatReader.setHints(QrCodeDecoder.EAN_13_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.HIGH_FREQUENCY) {
            mMultiFormatReader.setHints(QrCodeDecoder.HIGH_FREQUENCY_HINT_MAP);
        } else if (mQrCodeType == QrCodeType.CUSTOM) {
            mMultiFormatReader.setHints(mHintMap);
        } else {
            mMultiFormatReader.setHints(QrCodeDecoder.ALL_HINT_MAP);
        }
    }

    /**
     * 设置识别的格式
     *
     * @param barcodeType 识别的格式
     * @param hintMap     barcodeType 为 BarcodeType.CUSTOM 时，必须指定该值
     */
    public void setType(QrCodeType barcodeType, Map<DecodeHintType, Object> hintMap) {
        mQrCodeType = barcodeType;
        mHintMap = hintMap;
        if (mQrCodeType == QrCodeType.CUSTOM && (mHintMap == null || mHintMap.isEmpty())) {
            throw new RuntimeException("barcodeType 为 BarcodeType.CUSTOM 时 hintMap 不能为空");
        }
        setupReader();
    }
}
